"""
测试用例生成器
基于OpenAPI规范自动生成测试用例
"""

from typing import Dict, List, Any
from .openapi_parser import OpenAPIParser


class CaseGenerator:
    """测试用例生成器"""
    
    def __init__(self, parser: OpenAPIParser):
        self.parser = parser
    
    def generate_test_cases(self, project_id: int = None) -> List[Dict[str, Any]]:
        """
        从OpenAPI规范生成测试用例列表
        
        Args:
            project_id: 项目ID（可选）
            
        Returns:
            测试用例列表
        """
        test_cases = []
        paths = self.parser.get_paths()
        
        for path, methods in paths.items():
            for method, details in methods.items():
                # 跳过非HTTP方法的字段（如parameters、servers等）
                if method.lower() not in ['get', 'post', 'put', 'delete', 'patch', 'head', 'options']:
                    continue
                
                test_case = self._generate_single_case(path, method, details, project_id)
                test_cases.append(test_case)
        
        return test_cases
    
    def _generate_single_case(self, path: str, method: str, details: Dict[str, Any], 
                             project_id: int = None) -> Dict[str, Any]:
        """
        生成单个测试用例
        
        Args:
            path: API路径
            method: HTTP方法
            details: API详情
            project_id: 项目ID
            
        Returns:
            测试用例字典
        """
        # 生成唯一的用例ID
        case_id = f"{method.upper()}_{path.replace('/', '_').replace('{', '').replace('}', '')}"
        
        # 基础用例结构
        test_case = {
            "case_id": case_id,
            "case_name": details.get('summary', f"{method.upper()} {path}"),
            "url": path,
            "method": method.upper(),
            "description": details.get('description', '') or details.get('summary', ''),
            "parameters": [],
            "body": None,
            "assertions": [],
            "group_name": details.get('tags', ['default'])[0] if details.get('tags') else 'default',
            "status": "draft"
        }
        
        if project_id:
            test_case["project_id"] = project_id
        
        # 解析请求参数
        parameters = details.get('parameters', [])
        for param in parameters:
            param_info = self._parse_parameter(param)
            test_case['parameters'].append(param_info)
        
        # 解析请求体
        request_body = details.get('requestBody', {})
        if request_body:
            test_case['body'] = self._parse_request_body(request_body)
        
        # 生成基础断言
        responses = details.get('responses', {})
        test_case['assertions'] = self._generate_assertions(responses)
        
        return test_case
    
    def _parse_parameter(self, param: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析单个参数
        
        Args:
            param: 参数定义
            
        Returns:
            参数信息字典
        """
        schema = param.get('schema', {})
        
        return {
            "name": param.get('name', ''),
            "in": param.get('in', 'query'),  # path/query/header/cookie
            "required": param.get('required', False),
            "type": schema.get('type', 'string'),
            "description": param.get('description', ''),
            "example": self.parser.generate_example_value(schema)
        }
    
    def _parse_request_body(self, request_body: Dict[str, Any]) -> Dict[str, Any]:
        """
        解析请求体
        
        Args:
            request_body: 请求体定义
            
        Returns:
            请求体信息字典
        """
        content = request_body.get('content', {})
        
        # 优先处理JSON格式
        if 'application/json' in content:
            json_schema = content['application/json'].get('schema', {})
            return {
                "type": "json",
                "content": self.parser.generate_example_value(json_schema)
            }
        
        # 处理表单格式
        elif 'application/x-www-form-urlencoded' in content:
            form_schema = content['application/x-www-form-urlencoded'].get('schema', {})
            return {
                "type": "form",
                "content": self.parser.generate_example_value(form_schema)
            }
        
        # 处理multipart格式
        elif 'multipart/form-data' in content:
            multipart_schema = content['multipart/form-data'].get('schema', {})
            return {
                "type": "multipart",
                "content": self.parser.generate_example_value(multipart_schema)
            }
        
        return None
    
    def _generate_assertions(self, responses: Dict[str, Any]) -> List[Dict[str, Any]]:
        """
        生成基础断言规则
        
        Args:
            responses: 响应定义
            
        Returns:
            断言规则列表
        """
        assertions = []
        
        # 查找成功响应（2xx状态码）
        success_status = None
        for status_code in ['200', '201', '204']:
            if status_code in responses:
                success_status = status_code
                break
        
        if not success_status and responses:
            # 如果没有找到标准成功状态码，使用第一个2xx状态码
            for status_code in responses.keys():
                if status_code.startswith('2'):
                    success_status = status_code
                    break
        
        if success_status:
            # 添加状态码断言
            assertions.append({
                "type": "status_code",
                "operator": "==",
                "expected": int(success_status),
                "description": f"响应状态码应为{success_status}"
            })
            
            # 分析响应体结构，添加字段存在性断言
            response_def = responses[success_status]
            content = response_def.get('content', {})
            
            if 'application/json' in content:
                json_schema = content['application/json'].get('schema', {})
                
                # 如果响应体是对象，检查必需字段
                if json_schema.get('type') == 'object':
                    properties = json_schema.get('properties', {})
                    required_fields = json_schema.get('required', [])
                    
                    for field in required_fields:
                        assertions.append({
                            "type": "field_exists",
                            "field": field,
                            "description": f"响应体应包含字段: {field}"
                        })
        
        # 添加响应时间断言（默认5秒）
        assertions.append({
            "type": "response_time",
            "operator": "<",
            "expected": 5000,
            "description": "响应时间应小于5000毫秒"
        })
        
        return assertions
